package com.zzyl.nursing.utils;

import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.regex.Pattern;
@Component
public class IDCardUtils {
    // 身份证正则，18位标准格式
    private static final Pattern ID_PATTERN = Pattern.compile(
            "^[1-9]\\d{5}(19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");

    // 日期格式化器
    private static final DateTimeFormatter BIRTH_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    /**
     * 从身份证号提取生日，返回LocalDateTime(时分秒为0)
     */
    public static LocalDateTime extractBirthday(String idCard) {
        validateIdCard(idCard);
        String birthStr = idCard.substring(6, 14);
        try {
            LocalDate birthDate = LocalDate.parse(birthStr, BIRTH_FORMATTER);
            return birthDate.atStartOfDay();
        } catch (DateTimeParseException e) {
            throw new IllegalArgumentException("身份证出生日期无效: " + birthStr);
        }
    }

    /**
     * 从身份证号提取性别
     */
    public static Integer extractGender(String idCard) {
        validateIdCard(idCard);
        // 第17位数字，奇数男，偶数女
        int genderCode = Character.getNumericValue(idCard.charAt(16));
        return genderCode % 2 == 1 ? 1:0;

    }

    /**
     * 根据身份证号计算年龄
     */
    public static int calculateAge(String idCard) {
        LocalDate birthDate = extractBirthday(idCard).toLocalDate();
        LocalDate today = LocalDate.now();

        Period period = Period.between(birthDate, today);
        int age = period.getYears();

        // 没到今年生日，减一岁
        if (today.getMonthValue() < birthDate.getMonthValue()
                || (today.getMonthValue() == birthDate.getMonthValue()
                && today.getDayOfMonth() < birthDate.getDayOfMonth())) {
            age--;
        }

        return Math.max(0, age);
    }

    /**
     * 校验身份证号有效性
     */
    private static void validateIdCard(String idCard) {
        if (idCard == null || idCard.trim().isEmpty()) {
            throw new IllegalArgumentException("身份证号不能为空");
        }
        idCard = idCard.trim();

        if (idCard.length() != 18 || !ID_PATTERN.matcher(idCard).matches()) {
            throw new IllegalArgumentException("无效的身份证格式: " + idCard);
        }

        if (!checkVerifyCode(idCard)) {
            throw new IllegalArgumentException("身份证校验码错误: " + idCard);
        }
    }

    /**
     * 校验身份证第18位校验码
     */
    private static boolean checkVerifyCode(String idCard) {
        int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        char[] verifyCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += Character.getNumericValue(idCard.charAt(i)) * weights[i];
        }

        int mod = sum % 11;
        return Character.toUpperCase(idCard.charAt(17)) == verifyCodes[mod];
    }
}
